class Game {
  start() {
    const mapWidth = 40; // 格子个数
    const mapHeight = 30; // 格子个数

    const food = new Food(new Point(0, 0), mapWidth, mapHeight);
    food.newPosition();
    this.food = food;

    const snake = new Snake([new Point(0, 2), new Point(0, 1), new Point(0, 0)], "down", mapWidth, mapHeight);
    this.snake = snake;

    document.onkeydown = event => {
      switch (event.keyCode) {
        case 37:
          snake.direction = "left";
          break;
        case 38:
          snake.direction = "top";
          break;
        case 39:
          snake.direction = "right";
          break;
        case 40:
          snake.direction = "down";
          break;
      }
    };

    const interval = setInterval(() => {
      try {
        snake.step();
      } catch (e) {
        clearInterval(interval);
        alert(e.toString());
      }
      this.render();

      // 吃到食物
      if (snake.body[0].x === food.point.x && snake.body[0].y === food.point.y) {
        snake.body[snake.body.length] = snake.body[snake.body.length - 1];
        food.newPosition();
        while (snake.body.some(p => p.x === food.x && p.y === food.y)) { // 防止食物的位置与蛇的位置重合
          food.newPosition();
        }
      }
    }, 0.5e3);

    this.render();
  }

  render() {
    const map = document.getElementById("map");
    this.clear(map);
    this.createElement(map, this.food.point, "food");
    this.snake.body.forEach(p => this.createElement(map, p, "snake"));
  }

  clear(map) {
    while (map.children.length > 0) {
      map.removeChild(map.children[0]);
    }
  }

  createElement(map, point, pointType) {
    const sub = document.createElement("div");
    map.appendChild(sub);

    switch (pointType) {
      case "food":
        sub.className = "food";
        break;
      case "snake":
        sub.className = "snake";
        break;
    }

    const width = 10, height = 10;
    sub.style.left = point.x * width + "px";
    sub.style.top = point.y * height + "px";
  }
}

(() => {
  new Game().start();
})();
